## This is the player class as seen by the server, used by GameMaster

""" Revision system:

Each player keeps track of what object id's have been sent to the client, this is the key to the revision number of that object.

If a player has not had the current revision, it looks up the necessary properties to update and sends a dict package

Thus, a player reconnecting to his slot in the server would clear his object_knowledge, and require updates on everything in his game view.

"""
from starfield import Ship
import starfield
import random
from mathutils import Vector


class Player:
	def __init__(self, channel, GameMaster):
		self.channel = channel
		self.name = channel.nickname
		self.GameMaster = GameMaster
		self.curr_system = 0

		
		#player assets
		self.ships = []
		self.colonies = {}
		self.ships_by_system = {}
		self.ships_by_planets = {}
		
		#player knowledge
		self.known_systems = []
		self.object_knowledge = {} #id:revision 
		
		self.update_ticker = 0.0
		
	
	def Place(self, star):
		self.name = self.channel.nickname

		self.curr_system = star
		
		## add a ship
		self.addShip( star )
		
		self.explore( star )
		
		self.update_ticker = starfield.GameMaster.time
		

			
	def addShip(self, star):
		newship = Ship.Ship(star.location)
		newship.id = starfield.GameMaster.get_new_id()
		newship.player = self.name
		newship.star = star.id
		self.ships.append(newship)
		if star.name not in self.ships_by_system:
			self.ships_by_system[ star.name ] = []
			
		self.ships_by_system[ star.name ].append( newship )
		#'learn' about this ship
		self.object_knowledge[newship.id] = newship.revision
		
	def Pump(self, timestamp):
		#were going to handle ships every 2 seconds
		if timestamp > self.update_ticker + 2.0:
			self.update_ticker = timestamp
			for ship in self.ships:
				if ship.state != 1:
					if random.randint(0,5) == 2:
						currstar = starfield.GameMaster.galaxy.stars_by_id[ship.star]
						
						# temporary jitter in assigned location
						V = Vector( [ random.random()*5, random.random()*5, random.random()*5 ] )
						location = V
						
						ship.moveTo(location, timestamp)
						self.Send( { "action":"moveship", "id":ship.id, "target":list(location), "timestamp":timestamp} )
				else:
					ship.update(timestamp)
		
	def Send(self, data):
		self.channel.Send( data )
	
		
	def explore(self, star):
		if star not in self.known_systems:
			self.known_systems.append( star )
		discovered = [ star.serialize()]	
		
		self.channel.Send( {"action": "map", "stars":discovered} )
		self.report_ships(star)
		
	def report_ships(self, star):
		#Check this against player knowledge id base
		#should also update location for known ships, meaning a location memory?
		#perhaps a state counter to associate with id, 4:245 meaning id 4 is at state 245
		ships = []
		for player in self.GameMaster.players:
			if star.name in player.ships_by_system:
				for entry in player.ships_by_system[ star.name ]:
					ships.append(entry.serialize())
		if len(ships) > 0:

			self.channel.Send({"action": "ships", "ships":ships	} )
			pass
				
				
				
				
				
				
				
				